/**
 * 表格控件
 * @author Ly
 * @version 1.0a
 */
/**
 * Ly.DataGrid構造函數
 * @param {Object} container 承載控件的容器對象
 * @param {Object} config 控件的配置信息
 * config = {
     width : '100%',
     height : '100%',
     themes : 'default',
     baseCls : 'ly-datagrid',
     lineHeight : true,
     lineColor : '#FAFAFA',
	 rowEvents : {
	 }  // 作用于行的事件，返回行對象
 }
 */
Ly.DataGrid = function(container, config) {
    var _this = this;
    
    config = config || {};
    
    this.config = {
        id : 'ly-datagrid-' + Ly.getCount(),
        // 承載控件的容器對象，默認body
        container : container || document.body,
        width : config.width || '100%',
        height : config.height || '',
        themes : config.themes || 'default',
        baseCls : config.baseCls || 'ly-datagrid',
        style : config.style || '',
        lineHeight : typeof config.lineHeight == 'undefined' ? true : false,
        lineColor : config.lineColor || '#F0F1F3',
		rowEvents : config.rowEvents || {},
        dg : null,
        // 渲染模式
        model : [],
        // 列標題配置信息
        column : [],
        // 除列標題外的其他單元格配置信息
        grid : [],
        // 要綁定的數據
        data : [],
        // 被绑定事件的对象
        objList : [],
        // 翻頁工具倏信息
        pageInfo : {}
    };
    this.private = {
        /**
         * 獲取圖標
         */
        getIcon : function(t) {
            if (t == 'asc') {
                return '<img src="' + Ly.getPath() + 'images/' + _this.config.themes + '/datagrid/up.gif" border="0" />';
            } else {
                return '<img src="' + Ly.getPath() + 'images/' + _this.config.themes + '/datagrid/down.gif" border="0" />';
            }
        },
        /**
         * 存储用Ly.addEvent来添加事件的对象
         * @param {Object} obj 被添加事件的对象
         */
        saveObj : function(obj) {
            var
				c = _this.config,
            	oll = c.objList.length;
            
            for (var i = 0; i < oll; i++) {
                if (c.objList[i] === obj) {
                    return;
                }
            }
            c.objList.push(obj);
        },
		/**
		 * 初始化行事件
		 * @param {Object} row 要綁定事件的行對象
		 */
		initRowEvents : function(row /* Object */) {
			var _events = _this.config.rowEvents;
			
			for (var p in _events) {
				Ly.addEvent(p, _events[p], row);
			}
		},
        /**
         * 初始化控件框架
         */
        initDataGrid : function() {
            var
                c = _this.config,
				tb = Ly.createElement('tbody');
			c.dg = Ly.createElement('table', {
                id : c.id,
   	            border : 0,
       	        width : c.width,
           	    height : c.height,
           	    cls : c.baseCls,
           	    style : c.style
           	});
            
            c.container.appendChild(c.dg);
			c.dg.appendChild(tb);
			
			c.dg.cellSpacing = 0;
			c.dg.ceelPadding = 0;
        },
        /**
         * 初始化列標題
         */
        initColumnTitle : function() {
            var
                id,
                c = _this.config,
                cc = c.column,
                ccl = cc.length,
                tr = Ly.createElement('tr'),
                html = '';
            
            c.dg.firstChild.appendChild(tr);
            
            for (var i = 0; i < ccl; i++) {
                cc[i].id = 'ly-datagrid-title-' + Ly.getCount();
                
                var td = Ly.createElement('td', {
                    width : cc[i].width,
                    height : cc[i].height,
                    style : cc[i].style,
                    cls : cc[i].cls
                });
                tr.appendChild(td);
                
                td.innerHTML = '<div id="' + cc[i].id + '">' + cc[i].name + '<span style="vertical-align:middle;display:none"></span></div>';
                
                if (cc[i].order != '') {
                    var
						currentColumn = cc[i],
                    	currentColumnId = cc[i].id;
                    
					if (cc[i].events.onclick) {
						Ly.get(cc[i].id).style.cursor = 'pointer';
						Ly.addEvent('onclick',
							function(obj) {
								var
									cc = _this.config.column,
									co;
								// 清除其他的样式
								for (var i = 0; i < cc.length; i++) {
									if (cc[i].order != '') {
										Ly.get(cc[i].id).lastChild.innerHTML = '';
									}
									if (obj === Ly.get(cc[i].id)) {
										co = cc[i];
									}
								}
								
								// 如果用户自定义排序事件返回为false则不修改样式,否则修改
								var f = co.events.onclick(co.order);
								
								if (typeof f == 'undefined' || f) {
									Ly.get(co.id).lastChild.innerHTML = _this.private.getIcon(co.order);
									Ly.get(co.id).lastChild.style.display = '';
									
									co.order = (co.order == 'asc' ? 'desc' : 'asc');
								}
							},
							Ly.get(currentColumn.id)
						);
					} else {
						Ly.get(cc[i].id).style.cursor = 'default';
					}
                    this.saveObj(Ly.get(currentColumn.id));
                }
            }
        },
        /**
         * 初始化單元格
         * @param {Object} row 單元格所在的行對象
         * @param {Number} index 用來進行渲染的數組下標索引
         */
        initGrid : function(row, index) {
            var
                g = _this.config.grid[index],
                cols = row.childNodes,
                cl = cols.length;
            
            for (var i = 0; i < cl; i++) {
                cols[i].style.height = (g[i].height || '25') + 'px';
				cols[i].style.cssText += ';' + g[i].style || '';
                cols[i].className = g[i].baseCls || 'ly-datagrid-grid';
            }
        },
        /**
         * 初始化渲染模式，根據列標題格式生成默認的渲染模式
         */
        initModel : function() {
            var
                c = _this.config.column,
                cl = c.length,
                m = _this.config.model;
            
            if (m[0] && m[0].constructor == Array) {
                return;
            }
            m.push([]);
            for (var i = 0; i < cl; i++) {
                m[0].push({
                    colspan : 1,
                    rowspan : 1
                });
            }
        },
        /**
         * 加載數據
         */
        loadData : function() {
            var
                d = _this.config.data,
                dl = d.length;
            
            // 按行渲染
            for (var i = 0; i < dl;) {
                var
                    m = _this.config.model,
                    ml = m.length,
					onMouseOut = '',
					onMouseOver = '';
                
                // 查找渲染模式
                for (var j = 0; j < ml; j++) {
                    var
                        row,
                        html = '',
                        r = m[j],
                        rl /* rowsLength */ = r.length;
                    
					if (_this.config.lineHeight) {
						onMouseOut = 'javascript:this.className="ly-datagrid-row-onmouseout";';
						onMouseOver = 'javascript:this.className="ly-datagrid-row-onmouseover";';
					}
					row = Ly.createElement('tr', {
						cls : 'ly-datagrid-row-onmouseout',
						onmouseover : onMouseOver,
						onmouseout : onMouseOut
					});
					
                    _this.config.dg.firstChild.appendChild(row);
					
					_this.private.initRowEvents(row);
                    
                    // 按渲染模式進行渲染
                    for (var k = 0; k < rl; k++) {
                        var
							td = Ly.createElement('td', {
								 colSpan : r[k].colspan,
								 rowSpan : r[k].rowspan
							});
                        row.appendChild(td);
						td.innerHTML = d[i][k];
                    }
					// 初始化單元格屬性
					this.initGrid(row, j);
                    
                    if (++i <dl) {
                        continue;
                    } else {
                        break;
                    }
					row = null;
                }
            }
        },
        /**
         * 加載翻頁工具倏
         */
        loadPagingToolBar : function() {
            var
                tr = Ly.createElement('tr'),
				td = Ly.createElement('td', { cls : 'ly-datagrid-pagingtoolbar' }),
				tb = Ly.createElement('tbody'),
                c = _this.config,
                pi = c.pageInfo,
                rc = pi.rsCount,
                ps = pi.pageSize,
                cp = pi.currentPage,
                pc = pi.pageCount,
                themes = pi.themes,
                msg = pi.msg,
                id = c.id;
            
            pi.obj = Ly.createElement('table', {
                border : 0,
                width : _this.config.width,
                height : '20px'
            });
			pi.obj.cellSpacing = 0;
			pi.obj.cellPadding = 0;
			
			pi.obj.appendChild(tb);
            
            if (!pi.position) { return; }
            switch (pi.position.toLowerCase()) {
                case 'top':
                    c.container.insertBefore(pi.obj, _this.config.dg);
                    break;
                case 'bottom':
                    c.container.appendChild(pi.obj);
                    break;
            }
			// firstChild指的是tbody
            pi.obj.firstChild.appendChild(tr);
            tr.appendChild(td);
            td.innerHTML = '<div id="' + id + '-msg" class="ly-datagrid-ptb-msg">' + rc + '</div>' +
                '<div id="' + id + '-pageInfo" class="ly-datagrid-ptb-pageinfo">' + cp + '/' + pc + '</div>' +
                '<div id="' + id + '-first" class="ly-datagrid-ptb-paging">|&lt;</div>' +
                '<div id="' + id + '-previous" class="ly-datagrid-ptb-paging">&lt;&lt;</div>' +
                '<div id="' + id + '-next" class="ly-datagrid-ptb-paging">&gt;&gt;</div>' +
                '<div id="' + id + '-last" class="ly-datagrid-ptb-paging">&gt;|</div>' +
                '<div><input type="text" id="' + id + '-input" class="ly-datagrid-ptb-input" /></div>';
            this.addPageCode(Ly.get(id + '-next'));
            this.initPagingToolBarEvent(id);
        },
        /**
         * 給翻頁工具條添加頁碼
         * @param {Object} obj 將頁面添加到obj之前
         */
        addPageCode : function(obj) {
            var
                cls = 'ly-datagrid-ptb-page',
                pi = _this.config.pageInfo,
                cp = parseInt(pi.currentPage),
                pc = parseInt(pi.pageCount),
                start = 0,
                end = pc;
            
            start = (cp - 5) < 1 ? 1 : cp - 5;
            // 大於總頁
            if (start + 9 > pc) {
                end = pc;
                start = parseInt(pc - 9) < 1 ? 1 : pc - 9;    // 修正起始頁
            } else {
                end = start + 9;
            }
            
            for (var i = start; i <= end; i++) {
                var p = Ly.createElement('div', {
                        id : _this.config.id + '-' + i,
                        cls : cls
                    });
                obj.parentNode.insertBefore(p, obj);
                p.innerHTML = i;
                
                if (i == cp ) {
                    p.className = 'ly-datagrid-ptb-page-focus';
                } else {
                    p.className = 'ly-datagrid-ptb-page';
                    Ly.addEvent('onmouseover',
                        function(obj) {
                            obj.className = 'ly-datagrid-ptb-page-focus';
                        },
                        p);
                    Ly.addEvent('onmouseout',
                        function(obj) {
                            obj.className = 'ly-datagrid-ptb-page';
                        },
                        p);
                }
                Ly.addEvent('onclick',
                    function(obj) {
                        _this.config.pageInfo.currentPage = parseInt(obj.innerHTML);
                        _this.private.updatePTB();
                        _this.config.pageInfo.behavior(_this.config.pageInfo.currentPage);
                    },
                    p);
                this.saveObj(p);
				p = null;
            }
        },
        /**
         * 初始化工具倏事件
         * @param {String} id 工具倏所使用的ID
         */
        initPagingToolBarEvent : function(id) {
            var
                first = Ly.get(id + '-first'),
                previous = Ly.get(id + '-previous'),
                next = Ly.get(id + '-next'),
                last = Ly.get(id + '-last'),
                input = Ly.get(id + '-input');
            
            this.addPublicEvent(first);
            this.addPublicEvent(previous);
            this.addPublicEvent(next);
            this.addPublicEvent(last);
            
            document.onkeydown = function(event) {
                var
					e=event || window.event,
                	keyCode = e.keyCode ? e.keyCode : e.which ? e.which : e.charCode;
                
                if (keyCode == 0x0D){
                    var srcElement = e.srcElement || e.target;
                    
                    if (srcElement.id == _this.config.id + '-input'){
                        var
                            value = parseInt(Ly.get(_this.config.id + '-input').value),
                            pi = _this.config.pageInfo;
                        
						if (!Ly.isInt(value)) {
							alert('请输入合法的页码!');
							Ly.get(_this.config.id + '-input').value = '';
							return false;
						}
                        value = parseInt(value);
                        if (value < 1) {
                            value = 1;
                        }
                        if (value > pi.pageCount) {
                            value = pi.pageCount;
                        }
                        pi.currentPage = value;
                        pi.behavior(value);
                        Ly.get(_this.config.id + '-input').value = '';
                        _this.private.updatePTB();
                    }   
                }   
            };
            Ly.addEvent('onclick',
                function(obj) {
                    var pi = _this.config.pageInfo;
                    pi.currentPage = 1;
                    pi.behavior(1);
                    _this.private.updatePTB();
                },
                first);
            Ly.addEvent('onclick',
                function(obj) {
                    var pi = _this.config.pageInfo;
                    
                    pi.currentPage = --pi.currentPage < 1 ? 1 : pi.currentPage;
                    pi.behavior(pi.currentPage);
                    _this.private.updatePTB();
                },
                previous);
            Ly.addEvent('onclick',
                function(obj) {
                    var pi = _this.config.pageInfo;
                    
                    pi.currentPage = ++pi.currentPage > pi.pageCount ? pi.pageCount : pi.currentPage;
                    _this.config.pageInfo.behavior(pi.currentPage);
                    _this.private.updatePTB();
                },
                next);
            Ly.addEvent('onclick',
                function(obj) {
                    var pi = _this.config.pageInfo;
                    
                    pi.currentPage = pi.pageCount;
                    pi.behavior(pi.pageCount);
                    _this.private.updatePTB();
                },
                last);
            this.saveObj(first);
            this.saveObj(previous);
            this.saveObj(next);
            this.saveObj(last);
			first = null;
			previous = null;
			next = null;
			last = null;
			input = null;
        },
        /**
         * 添加公共事件
         * @param {Object} obj 要添加公共鼠標事件的對象
         */
        addPublicEvent : function(obj) {
            Ly.addEvent('onmouseover',
                function(obj) {
                    obj.className = 'ly-datagrid-ptb-paging-focus';
                },
                obj);
            Ly.addEvent('onmouseout',
                function(obj) {
                    obj.className = 'ly-datagrid-ptb-paging';
                },
                obj);
            this.saveObj(obj);
        },
        /**
         * 更新翻頁工具倏
         */
        updatePTB : function() {
            var
                obj,
				arr = ['first', 'previous', 'next', 'last'],
				c = _this.config,
                id = c.id,
                pi = c.pageInfo,
                tr = pi.obj,
                rc = pi.rsCount,
                cp = pi.currentPage,
                pc = pi.pageCount;
            
			for (var i = 0; i < 4; ++i) {
				obj = Ly.get(id + '-' + arr[i]);
				for (var j = 0; j < c.objList.length; ++j) {
					if (c.objList[j] === obj) {
						c.objList.splice(j, 1);
						break;
					}
				}
				Ly.removeEvent(obj);
				obj = null;
			}
			Ly.removeEvent(Ly.get(id + '-input'));
			
			// 定位到td
            tr.firstChild.firstChild.firstChild.innerHTML = '<div id="' + id + '-msg" class="ly-datagrid-ptb-msg">' + rc + '</div>' +
                '<div id="' + id + '-pageInfo" class="ly-datagrid-ptb-pageinfo">' + cp + '/' + pc + '</div>' +
                '<div id="' + id + '-first" class="ly-datagrid-ptb-paging">|&lt;</div>' +
                '<div id="' + id + '-previous" class="ly-datagrid-ptb-paging">&lt;&lt;</div>' +
                '<div id="' + id + '-next" class="ly-datagrid-ptb-paging">&gt;&gt;</div>' +
                '<div id="' + id + '-last" class="ly-datagrid-ptb-paging">&gt;|</div>' +
                '<div><input type="text" id="' + id + '-input" class="ly-datagrid-ptb-input" /></div>';
            
            this.addPageCode(Ly.get(id + '-next'));
            this.initPagingToolBarEvent(id);
        },
        /**
         * 更新控件視圖
         */
        updateView : function() {
            // 删除所有数据
            var
                t = Ly.get(_this.config.id);
            for (var i = t.rows.length - 1; i > 0; i--) {
                t.deleteRow(i);
            }
            this.loadData();
        }
    };
};
Ly.DataGrid.prototype = {
    version : '1.0a',
    /**
     * 設置列標題
     * @param {Array} config 配置信息
       config = [{
           name : '未命名',
           width : 60,
           height : 25,
           cls : 'ly-datagrid-title',
           style : '',
           order : false,
           events : {
               onclick : function(obj) {
               }
           }
       }]
     */
    columnModel : function(config) {
        if (config.constructor != Array) {
            alert('Ly.DataGrid控件的columnModel方法期望一個數組型參數!');
            return false;
        }
        
        for (var i = 0, len = config.length; i < len; i++) {
            this.config.column.push({
                name : config[i].name || '',
                width : config[i].width || '',
                height : config[i].height || '',
                cls : config[i].cls || 'ly-datagrid-title',
                style : config[i].style || '',
                order : config[i].order || 'asc',
                events : config[i].events || {}
            });
            
            // 初始化单元格模式
            this.config.grid.push([{
                height : 25,
                baseCls : 'ly-datagrid-grid',
                style : '',
                events : {}
            }]);
        }
    },
    /**
     * 設置單元格模式,存放模式的對象與渲染模式對象是同等數組
     * @param {Array} config 配置信息，設置多行即多參數
       config = [{
            height : 25,
            baseCls : 'ly-datagrid-grid',
            style : '',
            behavior : function(pageSize) {
            }
       }]
     */
    gridModel : function(config) {
        var
            arg = arguments,
            grid = this.config.grid;
        
        if (arg.length < 1) {
            alert('Ly.DataGrid控件的gridModel方法期望至少一個數組型參數！');
            return false;
        }
        
        this.config.grid = [];
        
        for (var i = 0; i < arg.length; i++) {
            if (arg[i].constructor != Array) {
                alert('Ly.DataGrid控件的gridModel方法期望至少一個數組型參數！');
                return false;
            }
            
            var data = [];
            
            for (var j = 0, len = arg[i].length; j < len; j++) {
                data.push({
                    height : arg[i][j].height || 25,
                    baseCls : arg[i][j].baseCls || 'ly-datagrid-grid',
                    style : arg[i][j].style || '',
                    events : arg[i][j].events || {}
                });
            }
            this.config.grid.push(data);
        }
    },
    /**
     * 渲染模式
     * @param {Array} config 模式配置信息
       config = [[{
                      colspan : 1,
                      rospan : 1
                  },{
                      colspan : 1,
                      rospan : 1
                  },{
                      colspan : 1,
                      rospan : 1
                  }],
                 [{
                      colspan : 2,
                    rospan : 1
                  },{
                      colspan : 1,
                      rospan : 1
                  }]
                 ]
     */
    renderModel : function(config) {
        if (config.constructor != Array) {
            alert('Ly.DataGrid控件的renderModel方法期望一個二維數組參數！');
            return false;
        }
        
        for (var i = 0, len = config.length; i < len; i++) {
            if (config[i].constructor != Array) {
                alert('Ly.DataGrid控件的renderModel方法期望一個二維數組參數！');
                return false;
            }
        }
        this.config.model = config;
    },
    /**
     * 綁定數據
     * @param {Array} data 要綁定的數據
     */
    bind : function(data) {
        if (data.constructor != Array) {
            alert('Ly.DataGrid控件的bind方法期望一個二維數組參數！');
            return false;
        }
        
        for (var i = 0, len = data.length; i < len; i++) {
            if (data[i].constructor != Array) {
                alert('Ly.DataGrid控件的bind方法期望一個二維數組參數！');
                return false;
            }
        }
        this.config.data = data;
    },
    /**
     * 渲染
     */
    render : function() {
        this.private.initDataGrid();
        this.private.initColumnTitle();
        this.private.initModel();
        this.private.loadData();
        this.private.loadPagingToolBar();
    },
    /**
     * 添加翻頁工具倏
     * @param {Object} config 配置信息
       config = {
           position: 'bottom',
           rsCount : 0,
           pageSize : 15,
           currentPage : 1,
           pageCount : 50,
           themes : 'default',
           msg : '',
           behavior : function(obj) {
           }
       }
     */
    pagingToolBar : function(config) {
        config = config || {};
        
        if (parseInt(config.pageCount) != config.pageCount) {
            //alert('Ly.DataGrid控件的paddingToolBar方法的config參數缺少必要信息pageCount！');
            return false;
        }
        
        this.config.pageInfo = {
            position : config.position || 'bottom',
            rsCount : config.rsCount || 0,
            pageSize : config.pageSize || 15,
            pageCount : config.pageCount,
            currentPage : config.currentPage || 1,
            themes : config.themes || 'default',
            msg : config.msg || '',
            behavior : config.behavior || function() {}
        };
    },
    /**
     * 更新翻頁工具倏信息
     * @param {Object} config 配置信息
       config = {
           pageSize : 15,
           pageCount : 50,
           themes : 'default',
           msg : ''
       }
     */
    updatePagingToolBar : function(config) {
        var c = this.config.pageInfo;
        c.rsCount = config.rsCount || c.rsCount;
        c.pageSize = config.pageSize || c.pageSize;
        c.pageCount = config.pageCount || c.pageCount;
        c.currentPage = config.currentPage || c.currentPage;
        c.themes = config.themes || c.themes;
        c.msg = config.msg || c.msg;
        c.behavior = config.behavior || c.behavior;
        
        this.private.updatePTB();
    },
    /**
     * 更新表格視圖
     * @param {Array} data 用来更新视力的数据
     */
    update : function(data) {
        this.bind(data);
        this.private.updateView();
    },
    /**
     移除DataGrid控件
     */
    remove : function() {
        var
			c = this.config,
        	o = c.objList;
        
        for (var i = 0, len = o.length; i < len; i++) {
            Ly.removeEvent(o[i]);
        }
        
		c.dg.removeChild(c.dg.firstChild);
        c.container.removeChild(c.dg);
        try {
            c.container.removeChild(c.pageInfo.obj);
        } catch (e) {}
    },
	/**
	 * 獲取DATAGRID控件信息
	 */
	getInfo : function() {
		return this.config;
	}
};